﻿using System;
using EPiServer.Common;
using EPiServer.Community.Blog;
using JoelAbrahamsson.TestUtilities;
using Moq;
using StructureMap.AutoMocking;
using Xunit;

namespace JoelAbrahamsson.MetaWeblog.Tests
{
    public class SetEntryPropertiesTests
    {
        [Fact]
        public void SetEntryProperties_SetsEntryTitle()
        {
            Mock<Entry> fakeEntry = new Mock<Entry>();
            fakeEntry.SetupProperty(entry => entry.Title);
            Post post = new Post { title = RandomValues.String };
            Mock<MetaWeblogHandler> metaWeblogHandler = CreatePartiallyFakeMetaWeblogHandler();

            metaWeblogHandler.Object.SetEntryProperties(fakeEntry.Object, post, new Mock<IAuthor>().Object);

            Assert.Equal<string>(post.title, fakeEntry.Object.Title);
        }

        private Mock<MetaWeblogHandler> CreatePartiallyFakeMetaWeblogHandler()
        {
            return Mock.Get(CreatePartiallyFakeMetaWeblogHandlerAutoMocker().ClassUnderTest);
        }

        private MoqAutoMocker<MetaWeblogHandler> CreatePartiallyFakeMetaWeblogHandlerAutoMocker()
        {
            MoqAutoMocker<MetaWeblogHandler> metaWeblogHandlerAutoMocker = new MoqAutoMocker<MetaWeblogHandler>();
            metaWeblogHandlerAutoMocker.PartialMockTheClassUnderTest();
            
            Mock<MetaWeblogHandler> fakeMetaWeblogHandler = Mock.Get(metaWeblogHandlerAutoMocker.ClassUnderTest);
            fakeMetaWeblogHandler.Setup(handler => handler.UpdateEntryCategories(It.IsAny<Entry>(), It.IsAny<string[]>()));
            fakeMetaWeblogHandler.Setup(handler => handler.UpdateEntryTags(It.IsAny<Entry>(), It.IsAny<string>(), It.IsAny<IAuthor>()));
            
            Mock.Get(metaWeblogHandlerAutoMocker.Get<IBlogEntryExcerptProvider>()).Setup(provider => provider.SetExcerpt(It.IsAny<Entry>(), It.IsAny<string>()));
            Mock.Get(metaWeblogHandlerAutoMocker.Get<IBlogEntrySlugProvider>()).Setup(provider => provider.SetSlug(It.IsAny<Entry>(), It.IsAny<string>()));
            
            return metaWeblogHandlerAutoMocker;
        }

        [Fact]
        public void SetEntryProperties_SetsEntryContent()
        {
            Mock<Entry> fakeEntry = new Mock<Entry>();
            fakeEntry.SetupProperty(entry => entry.Content);
            Post post = new Post { description = RandomValues.String };
            Mock<MetaWeblogHandler> metaWeblogHandler = CreatePartiallyFakeMetaWeblogHandler();

            metaWeblogHandler.Object.SetEntryProperties(fakeEntry.Object, post, new Mock<IAuthor>().Object);

            Assert.Equal<string>(post.description, fakeEntry.Object.Content);
        }

        [Fact]
        public void SetEntryProperties_SetsEntryPublicationStart()
        {
            Mock<Entry> fakeEntry = new Mock<Entry>();
            fakeEntry.SetupProperty(entry => entry.PublicationStart);
            Post post = new Post { dateCreated = DateTime.Now };
            Mock<MetaWeblogHandler> metaWeblogHandler = CreatePartiallyFakeMetaWeblogHandler();

            metaWeblogHandler.Object.SetEntryProperties(fakeEntry.Object, post, new Mock<IAuthor>().Object);

            Assert.Equal<DateTime>(post.dateCreated, fakeEntry.Object.PublicationStart);
        }

        [Fact]
        public void SetEntryProperties_SetsEntryExcerpt()
        {
            Mock<Entry> fakeEntry = new Mock<Entry>();
            Post post = new Post { mt_excerpt = RandomValues.String };
            MoqAutoMocker<MetaWeblogHandler> metaWeblogHandlerAutoMocker = CreatePartiallyFakeMetaWeblogHandlerAutoMocker();
            
            metaWeblogHandlerAutoMocker.ClassUnderTest.SetEntryProperties(fakeEntry.Object, post, new Mock<IAuthor>().Object);

            Mock.Get(metaWeblogHandlerAutoMocker.Get<IBlogEntryExcerptProvider>()).Verify(provider => provider.SetExcerpt(fakeEntry.Object, post.mt_excerpt));
        }

        [Fact]
        public void SetEntryProperties_SetsEntrySlug()
        {
            Mock<Entry> fakeEntry = new Mock<Entry>();
            Post post = new Post { wp_slug = RandomValues.String };
            MoqAutoMocker<MetaWeblogHandler> metaWeblogHandlerAutoMocker = CreatePartiallyFakeMetaWeblogHandlerAutoMocker();

            metaWeblogHandlerAutoMocker.ClassUnderTest.SetEntryProperties(fakeEntry.Object, post, new Mock<IAuthor>().Object);

            Mock.Get(metaWeblogHandlerAutoMocker.Get<IBlogEntrySlugProvider>()).Verify(provider => provider.SetSlug(fakeEntry.Object, post.wp_slug));
        }

        [Fact]
        public void SetEntryProperties_UpdatesEntryCategories()
        {
            Mock<Entry> fakeEntry = new Mock<Entry>();
            Post post = new Post { categories = new string[0]};
            Mock<MetaWeblogHandler> metaWeblogHandler = CreatePartiallyFakeMetaWeblogHandler();

            metaWeblogHandler.Object.SetEntryProperties(fakeEntry.Object, post, new Mock<IAuthor>().Object);

            metaWeblogHandler.Verify(handler => handler.UpdateEntryCategories(fakeEntry.Object, post.categories));
        }

        [Fact]
        public void SetEntryProperties_UpdatesEntryTags()
        {
            Mock<Entry> fakeEntry = new Mock<Entry>();
            Post post = new Post { mt_keywords = string.Empty };
            Mock<MetaWeblogHandler> metaWeblogHandler = CreatePartiallyFakeMetaWeblogHandler();

            metaWeblogHandler.Object.SetEntryProperties(fakeEntry.Object, post, new Mock<IAuthor>().Object);

            metaWeblogHandler.Verify(handler => handler.UpdateEntryTags(fakeEntry.Object, post.mt_keywords, It.IsAny<IAuthor>()));
        }
    }
}
